From a4a2d7618250407fa78cb5cd3184b7d20a11a7e8 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Fri, 21 Jan 2011 12:37:35 -0600 Subject: [PATCH] bgo#639531 - [filechooser] Handle the case where the user types a nonexistent_subfolder/file.txt The logic was to try to switch to that nonexistent folder and thus get an error message presented. However, no such message actually appears, as the file chooser tries to switch to the closest parent folder that actually exists, without bringing up an error message --- this is done to cope with the case of the file chooser being started with a folder that doesn't exist anymore. Now, we just bring up an error message directly when we detect that the user types a subfolder name that doesn't exist. Signed-off-by: Federico Mena Quintero --- gtk/gtkfilechooserdefault.c | 63 ++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index 2a5adf9b92..8ffd758a05 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -993,6 +993,21 @@ error_creating_folder_over_existing_file_dialog (GtkFileChooserDefault *impl, file, error); } +static void +error_with_file_under_nonfolder (GtkFileChooserDefault *impl, + GFile *parent_file) +{ + GError *error; + + error = NULL; + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, + _("You need to choose a valid filename.")); + + error_dialog (impl, + _("Cannot create a file under %s as it is not a folder"), + parent_file, error); +} + /* Shows an error about not being able to select a folder because a file with * the same name is already there. */ @@ -8200,7 +8215,11 @@ name_entry_get_parent_info_cb (GCancellable *cancellable, if (parent_is_folder) { - if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) + if (data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) + { + g_signal_emit_by_name (data->impl, "response-requested"); /* even if the file doesn't exist, apps can make good use of that (e.g. Emacs) */ + } + else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) { if (data->file_exists_and_is_not_folder) { @@ -8224,28 +8243,40 @@ name_entry_get_parent_info_cb (GCancellable *cancellable, else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) { - GError *error = NULL; + GError *mkdir_error = NULL; /* In both cases (SELECT_FOLDER and CREATE_FOLDER), if you type * "/blah/nonexistent" you *will* want a folder created. */ set_busy_cursor (data->impl, TRUE); - g_file_make_directory (data->file, NULL, &error); + g_file_make_directory (data->file, NULL, &mkdir_error); set_busy_cursor (data->impl, FALSE); - if (!error) + if (!mkdir_error) g_signal_emit_by_name (data->impl, "response-requested"); else - error_creating_folder_dialog (data->impl, data->file, error); + error_creating_folder_dialog (data->impl, data->file, mkdir_error); } else g_assert_not_reached (); } else { - /* This will display an error, which is what we want */ - change_folder_and_display_error (data->impl, data->parent_file, FALSE); + if (info) + { + /* The parent exists, but it's not a folder! Someone probably typed existing_file.txt/subfile.txt */ + error_with_file_under_nonfolder (data->impl, data->parent_file); + } + else + { + GError *error_copy; + + /* The parent folder is not readable for some reason */ + + error_copy = g_error_copy (error); + error_changing_folder_dialog (data->impl, data->parent_file, error_copy); + } } out: @@ -8267,7 +8298,7 @@ file_exists_get_info_cb (GCancellable *cancellable, gboolean cancelled = g_cancellable_is_cancelled (cancellable); gboolean file_exists; gboolean is_folder; - gboolean needs_file_type_check = FALSE; + gboolean needs_parent_check = FALSE; struct FileExistsData *data = user_data; if (cancellable != data->impl->file_exists_get_info_cancellable) @@ -8289,8 +8320,10 @@ file_exists_get_info_cb (GCancellable *cancellable, change_folder_and_display_error (data->impl, data->file, TRUE); else { - /* user typed a filename; we are done */ - g_signal_emit_by_name (data->impl, "response-requested"); + if (file_exists) + g_signal_emit_by_name (data->impl, "response-requested"); /* user typed an existing filename; we are done */ + else + needs_parent_check = TRUE; /* file doesn't exist; see if its parent exists */ } } else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) @@ -8305,14 +8338,14 @@ file_exists_get_info_cb (GCancellable *cancellable, } else { - needs_file_type_check = TRUE; + needs_parent_check = TRUE; } } else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) { if (!file_exists) { - needs_file_type_check = TRUE; + needs_parent_check = TRUE; } else { @@ -8330,15 +8363,15 @@ file_exists_get_info_cb (GCancellable *cancellable, if (is_folder) change_folder_and_display_error (data->impl, data->file, TRUE); else - needs_file_type_check = TRUE; + needs_parent_check = TRUE; } else { g_assert_not_reached(); } - if (needs_file_type_check) { - /* check that everything up to the last component exists */ + if (needs_parent_check) { + /* check that everything up to the last path component exists (i.e. the parent) */ data->file_exists_and_is_not_folder = file_exists && !is_folder; data_ownership_taken = TRUE; -- 2.30.2